#!/usr/bin/env python2
# -*- coding: utf-8 -*-

# Copyright (c) 2011 Alexandre Défossez
# This file is part of HINAPT.
#
# HINAPT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# HINAPT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with HINAPT.  If not, see <http://www.gnu.org/licenses/>.

"""
Script pour mettre à jour l'ensemble d'entraînement négatif durant
l'entraînement de Viola-Jones, seuls les exemples mal classifiés sont
gardés et de nouveaux sont générés si nécessaire.
Nécessite: (paquets Archlinux)
    - python-imaging
"""

import math
import os
import os.path
import random
import hashlib
from cStringIO import StringIO
from subprocess import call
import time
import ctypes

import Image

EXAMPLE_FOLDER = "trainPic/nonfaceTrain/"
SAMPLE_FOLDER = "img_sample"
CHECKER_PATH = "bin/libcheck.so"
N_IMG = 100000

checker = ctypes.cdll.LoadLibrary(CHECKER_PATH)
checker.check.argtypes = [ctypes.c_char_p]
checker.check.restype = ctypes.c_int


def rand_sub(img):
    w,h = img.size
    x1 = random.randrange(0, w-19)
    y1 = random.randrange(0, h-19)
    c = random.randrange(19, min(h-y1, w-x1))
    return img.crop((x1, y1, x1+c, y1+c)).resize((19, 19))

def get_an_example():
    l = [i for i in os.listdir(SAMPLE_FOLDER) if not i.startswith(".")]
    fname = random.sample(l, 1)[0]
    img = Image.open(os.path.join(SAMPLE_FOLDER,fname))
    sub = rand_sub(img)
    f = StringIO()
    sub.save(f, "ppm")
    s = f.getvalue()
    n = hashlib.md5(s).hexdigest()+".pgm"
    name = os.path.join(EXAMPLE_FOLDER,n)
    if os.path.exists(name):
        return get_an_example()
    else:
        open(name, "w").write(s)
        return name

def check(n):
    r = checker.check(n)
    return r==0

n_kept = 0
n_removed = 0
for i in os.listdir(EXAMPLE_FOLDER):
    j = os.path.join(EXAMPLE_FOLDER, i)
    if check(j):
        n_removed += 1
        os.unlink(j)
        j = get_an_example()
    else:
        n_kept += 1
        continue
    while check(j):
        os.unlink(j)
        j = get_an_example()

n_added = N_IMG - len(os.listdir(EXAMPLE_FOLDER))
for i in range(len(os.listdir(EXAMPLE_FOLDER)), N_IMG):
    j = get_an_example()
    while check(j):
        os.unlink(j)
        j = get_an_example()

print "kept: %i\nremoved: %i\nadded: %i"%(n_kept, n_removed, n_added)
